package com.ktkj.init.controller;

import com.ktkj.init.exception.BusinessException;
import com.ktkj.init.response.Response;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 大文件分片上传.
 *
 * @author :yanlixiong
 * @date :2022-02-18 17:37:48
 */
@Api(tags = "大文件分片上传管理")
//@ApiIgnore
@Controller
@RequestMapping("/upload")
@CrossOrigin
@Slf4j
public class UploadController {
    //String html = "D:\\idea_workspace_kt\\project\\HTML\\upload.html";

    @Value("${upload.file.path}")
    private String filePath;


    /**
     * 上传文件.
     *
     * @param request the request
     * @param guid    the 前端随机生成的GUID
     * @param chunk   the 当前分片序号（从0开始）
     * @param file    the file
     * @param chunks  the 分片总数量
     * @author :yanlixiong
     * @date :2022-02-18 17:38:55
     */
    @ResponseBody
    @PostMapping("/uploadFile")
    public void uploadFile(HttpServletRequest request, String guid, Integer chunk, MultipartFile file, Integer chunks) {
        try {
            if (chunk == null || chunks == null) {
                chunk = 0;
                chunks = 1;
            }
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (isMultipart) {
                // 临时目录用来存放所有分片文件
                String tempFileDir = filePath + guid;
                File parentFileDir = new File(tempFileDir);
                if (!parentFileDir.exists()) {
                    parentFileDir.mkdirs();
                }
                // 分片处理时，前台会多次调用上传接口，每次都会上传文件的一部分到后台
                String tempFileName = guid + "_" + chunk + ".part";
                File tempPartFile = new File(parentFileDir, tempFileName);
                log.info("guid:{}", guid);
                log.info("fileName:{}", file.getOriginalFilename());
                log.info("tempFileName:{}", tempFileName);
                log.info("chunk:{},chunks:{}", chunk, chunks);
                log.info("---------------------------------");
                FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);
            }
        } catch (Exception e) {
            log.error("上传文件.error|", e);
        }
    }


    /**
     * 合并文件.
     *
     * @param guid     the 前端随机生成的GUID
     * @param fileName the file name
     * @return the response
     * @author :yanlixiong
     * @date :2022-02-18 17:43:46
     */
    @ResponseBody
    @PostMapping("/mergeFile")
    public Response mergeFile(String guid, String fileName) {
        try {
            log.info("guid:{}", guid);
            log.info("fileName:{}", fileName);
            File parentFileDir = new File(filePath + guid);
            if (parentFileDir.isDirectory()) {
                File desTempFile = new File(filePath + File.separator + "merge", fileName);
                if (!desTempFile.exists()) {
                    //先得到文件的上级目录，并创建上级目录，在创建文件,
                    desTempFile.getParentFile().mkdir();
                    try {
                        //创建文件 上级目录没有创建，这里会报错
                        desTempFile.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                int fileLength = parentFileDir.listFiles().length;
                for (int i = 0; i < parentFileDir.listFiles().length; i++) {
                    File partFile = new File(parentFileDir, guid + "_" + i + ".part");
                    FileOutputStream desTempFos = new FileOutputStream(desTempFile, true);
                    //遍历"所有分片文件"到"最终文件"中
                    FileUtils.copyFile(partFile, desTempFos);
                    desTempFos.close();
                }
                // 删除临时目录中的分片文件
                FileUtils.deleteDirectory(parentFileDir);
                log.info("分片总数量|{}", fileLength);
                log.info("最终合并文件路径|{}", desTempFile.getPath());
            }
        } catch (Exception e) {
            log.error("合并文件失败！|", e);
            throw new BusinessException(BusinessException.BUSSINESS_EXCEPTION, "合并文件失败！");
        }
        return Response.ok(true);
    }
}
